use criterion::{Criterion, criterion_group, criterion_main};
use serde::{Deserializer, de};
use sonic_rs::{Deserialize, JsonValueTrait};
use std::str::FromStr;

fn string_to_f64<'de, D>(deserializer: D) -> Result<f64, D::Error>
where
    D: Deserializer<'de>,
{
    let s = String::deserialize(deserializer)?;
    f64::from_str(&s).map_err(de::Error::custom)
}

#[derive(Deserialize)]
struct Ticker {
    #[serde(deserialize_with = "string_to_f64")]
    a: f64,
    #[serde(deserialize_with = "string_to_f64")]
    b: f64,
}

const TEST_STR: &[u8; 141] = b"{\"e\":\"bookTicker\",\"u\":7037035488616,\"s\":\"BTCUSDT\",\"b\":\"84297.50\",\"B\":\"3.873\",\"a\":\"84297.60\",\"A\":\"12.831\",\"T\":1742100584448,\"E\":1742100584448}";

#[inline]
// 第一个函数：计算平方
fn one() {
    let a: Ticker = unsafe { sonic_rs::from_slice_unchecked(TEST_STR) }.unwrap();
}

#[inline]
// 第二个函数：计算立方
fn second() {
    let a = unsafe { sonic_rs::get_from_slice_unchecked(TEST_STR, &["a"]).unwrap() }
        .as_str()
        .unwrap()
        .parse::<f64>()
        .unwrap();
    let b = unsafe { sonic_rs::get_from_slice_unchecked(TEST_STR, &["b"]).unwrap() }
        .as_str()
        .unwrap()
        .parse::<f64>()
        .unwrap();
}

// 对比测试
fn compare_math(c: &mut Criterion) {
    let mut group = c.benchmark_group("Math Functions");

    // 测试平方函数
    group.bench_function("Square", |b| b.iter(one));

    // 测试立方函数
    group.bench_function("Cube", |b| b.iter(second));

    group.finish();
}

criterion_group!(benches, compare_math);
criterion_main!(benches);
